package cn.dengta.webapp.trade.entity;

import java.math.BigDecimal;
import java.util.Date;

import cn.dengta.common.model.BizFlag;
import cn.dengta.common.util.Formats;
import cn.dengta.common.web.Client;
import cn.dengta.webapp.base.entity.TimeBasedEntity;
import cn.dengta.webapp.trade.model.*;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import me.codeplayer.util.RandomUtil;
import me.codeplayer.util.StringUtil;

/**
 * 支付订单
 *
 * @author yuqidi
 * @since 2022-03-14
 */
@Setter
@Getter
@Accessors(chain = true)
@TableName("tr_recharge_log")
public class RechargeLog extends TimeBasedEntity implements BizFlag.WritableBizFlag {

	/** 首充 */
	public static final long BIZ_FLAG_FIRST_FLAG = 1L;
	/** 首充且领取了首充礼包 */
	public static final long BIZ_FLAG_FIRST_FLAG_GIFTS = 1L << 1;
	/** 充值时是否VIP */
	public static final long BIZ_FLAG_IS_VIP = 1L << 2;
	//
	/** 首充赠送1天VIP */
	public static final int FIRST_SEND_VIP_DAY = 1;
	/** 首充赠送30钻石 */
	public static final int FIRST_SEND_COIN = 30;

	/** 本地订单号，不一样的平台可能 order_no = trade_no */
	protected String orderNo;
	/** 第三方订单号（来自在线支付平台） */
	protected String tradeNo;
	/** 用户ID */
	protected Long userId;
	/** 类型：1=充值钻石；2=VIP充值；3=购买提升搭讪推荐曝光率服务；4=积分兑换 @see PayType */
	protected Integer type;
	/** 充值钻石数（不包含免费赠送的钻石数） */
	protected Integer coin;
	/** 免费赠送的钻石数（不含VIP免费赠送数） */
	protected Integer freeCoin;
	/** 如果用户是VIP，额外赠送的虚拟币 */
	protected Integer vipFreeCoin;
	/** 商品标价 */
	protected BigDecimal price;
	/** 实际支付总额 （美元） */
	protected BigDecimal realPay;
	/** 支付平台：1=Google；2=Apple；3=PayPal；4=Payoneer */
	protected Integer platform;
	/** 商户别名：用于支持同一支付平台的多商户配置并存 */
	protected String alias;
	/**
	 * 客户端类型：2=Android；3=iOS
	 *
	 * @see cn.dengta.common.web.Client
	 */
	protected Client client;
	/**
	 * 充值状态：-99=已关闭；-2=已退款；-1=退款中；0=待支付；1=处理中；2=已支付成功
	 *
	 * @see cn.dengta.webapp.trade.model.RechargeStatus
	 */
	protected Integer status;
	/** 备注 */
	protected String remark;
	/** 退款总数 */
	protected BigDecimal refundSum;
	/** 退款次数 */
	protected Integer refundCount;
	/** 第三方支付平台的内购商品代号（ID） */
	protected String productCode;
	/** 内购商品ID */
	protected Long productId;
	/** 基于位运算的业务标识 */
	protected long bizFlag;
	/** 首充标识：是否领取了首充礼包 */
	@TableField(exist = false)
	protected Boolean giftFlag;
	/** 首充标识：0=不是首充；1=是首充；2=首充且领取了首充礼包 */
	@TableField(exist = false)
	protected Boolean firstFlag;
	/** 当前是否是VIP */
	@TableField(exist = false)
	protected Boolean isVip;
	/** 处理状态 */
	protected Integer handleStatus;
	/** VIP开始时间 */
	private Date vipStartTime;
	/** VIP天数 */
	private Integer vipDays;
	/** VIP配置ID */
	private Long vipConfigId;
	/** 国家 */
	private String country;
	/** 币种 */
	private String currency;
	/** 操作目标类型 */
	private String assocType;
	/** 操作目标ID */
	private Long assocId;
	/** 渠道 */
	private String channel;
	/** 充值场景 json 格式 */
	private String scenes;
	/** @see SourceType 来源 */
	private Integer source;
	/** 充值结果信息 */
	@TableField(typeHandler = FastjsonTypeHandler.class)
	private JSONObject payResInfo;
	/** 代理人账户id */
	private Long proxyAccountId;
	/** 分包信息 */
	private Integer weskit;
	/** 真实人民币价格 */
	private BigDecimal realPriceCny;

	private transient ScenesTypeLog typeLog;

	public boolean OK() {
		return RechargeStatus.OK.eq(status);
	}

	public void setBizFlag(long bizFlag) {
		this.bizFlag = bizFlag;
	}

	public Boolean getFirstFlag() {
		return hasFlag(BIZ_FLAG_FIRST_FLAG);
	}

	public Boolean getIsVip() {
		return hasFlag(BIZ_FLAG_IS_VIP);
	}

	public void setIsVip(long isVip) {
		addFlag(isVip);
	}

	public Boolean getGiftFlag() {
		return hasFlag(BIZ_FLAG_FIRST_FLAG_GIFTS);
	}

	public static RechargeLog adminOf(RechargeProduct rechargeProduct, Long rechargeUserId, Date date) {
		RechargeLog rechargeLog = new RechargeLog();
		rechargeLog.setFreeCoin(0).setCoin(0).setProductCode(rechargeProduct.getCode()).setProductId(rechargeProduct.getId()).setPlatform(0).setVipStartTime(date)
				.setUserId(rechargeUserId).setClient(Client.SYSTEM).setStatus(2).setRealPay(BigDecimal.ZERO).setPrice(BigDecimal.ZERO).setVipDays(rechargeProduct.getVipDays())
				.setPlatform(0).setType(rechargeProduct.getType());
		rechargeLog.initTime(date);
		final String orderNo = Formats.formatDate(date, "yyyyMMddHHmmssSSS") + "_" + RandomUtil.getIntString(6);
		rechargeLog.setOrderNo(orderNo);

		return rechargeLog;
	}

	public boolean finished() {
		return RechargeStatus.OK.eq(status) || RechargeStatus.CLOSED.eq(status);
	}

	/**
	 * 指示是否还能接受支付成功的回调处理
	 */
	public boolean canPay() {
		return RechargeStatus.INIT.eq(status) || RechargeStatus.PENDING.eq(status);
	}

	public ScenesType getScenesType() {
		if (this.typeLog == null && StringUtil.notEmpty(this.scenes)) {
			this.typeLog = JSONObject.parseObject(this.scenes, ScenesTypeLog.class);
			return ScenesType.of(this.typeLog.getScenes());
		}
		if (this.typeLog != null) {
			return ScenesType.of(this.typeLog.getScenes());
		}
		return null;
	}

	public Long getGiftId() {
		if (this.typeLog == null && StringUtil.notEmpty(this.scenes)) {
			typeLog = JSONObject.parseObject(this.scenes, ScenesTypeLog.class);
		}
		if (this.typeLog != null) {
			return this.typeLog.getBusId();
		}
		return null;
	}

	public static final String ORDER_NO = "order_no";
	public static final String TRADE_NO = "trade_no";
	public static final String USER_ID = "user_id";
	public static final String COIN = "coin";
	public static final String PRICE = "price";
	public static final String TYPE = "type";
	public static final String PLATFORM = "platform";
	public static final String CLIENT = "client";
	public static final String REAL_PAY = "real_pay";
	public static final String REFUND_SUM = "refund_sum";
	public static final String REFUND_COUNT = "refund_count";
	public static final String PRODUCT_ID = "product_id";
	public static final String PRODUCT_CODE = "product_code";
	public static final String VIP_DAYS = "vip_days";
	public static final String REMARK = "remark";
	public static final String SOURCE = "source";
	public static final String STATUS = "status";
	public static final String PROXY_ACCOUNT_ID = "proxy_account_id";

	@Getter
	@Setter
	public static final class ScenesTypeLog {

		/** 场景 @see cn.dengta.webapp.trade.model.ScenesType */
		private Integer scenes;
		/** 业务id>礼物id */
		private Long busId;
		/** 别名 > 如游戏别名 */
		private String alias;

	}

}
